#include "StdAfx.h"
#include "DrawButton.h"
namespace UILib
{

    CDrawButton::CDrawButton(void) : CDrawView( NULL, -1, NULL )\
        , pBitMap_(NULL)\
        , pIcon_(NULL)\
        , nStatusCount_(4)\
        , nSelIndex_(0)\
        , nStatusOfSel_(4)\
        , nTextOff_(0)\
        , bGDIPlushEnable_(false)
    {
        memset(&pSplit_, 0, sizeof(SplitPos));
    }

    CDrawButton::CDrawButton( Bitmap* pBitmap, const PUIRect pRect, const PSplitPos pSplit, const UINT uID /*= -1*/, const int nStatusCount /*= 4*/, ViewListener* pListener /*= NULL */ )
    : CDrawView( pRect, uID, pListener )\
    , pBitMap_(pBitmap)\
    , nStatusCount_(nStatusCount)\
    , pIcon_(NULL)\
    , nSelIndex_(0)\
    , nStatusOfSel_(4)\
    , nTextOff_(0)\
    , bGDIPlushEnable_(false)
    {
        if ( pSplit )
        {
            memcpy(&pSplit_, pSplit, sizeof(SplitPos) );
        }
        else
        {
            memset(&pSplit_, 0, sizeof(SplitPos));
        }
    }
    CDrawButton::~CDrawButton(void)
    {
    }

    void CDrawButton::DrawElement( const HDC hDC, const RECT &rcPaint )
    {
        CDrawView::bNeedInvalidate_ = false;
        if ( pBitMap_ == NULL ||  nStatusCount_ == 0 || !IsVisible() )
        {
            return;
        }
        int nW = pBitMap_->GetWidth();
        int nH = pBitMap_->GetHeight();

        RECT rcEmem = { 0 };
        CDrawView::GetRECT(rcEmem);

        Elem_Status eStatus = CDrawView::GetStatus();
        if ( !CDrawView::IsEnable() )
        {
            eStatus = Elem_Disable;
        }
        Graphics graph(hDC);
        if ( pSplit_.lBegin == pSplit_.lEnd )
        {
            Rect rcDest(rcEmem.left, rcEmem.top, rcEmem.right - rcEmem.left, rcEmem.bottom - rcEmem.top );
            graph.DrawImage(pBitMap_, rcDest, (nW/nStatusCount_)* (eStatus + nSelIndex_*nStatusOfSel_), 0, nW/nStatusCount_, nH, UnitPixel, NULL, NULL, NULL);
        }
        else
        {
            int nStatusW = nW/nStatusCount_;
            SIZE szElem = { rcEmem.right - rcEmem.left, rcEmem.bottom - rcEmem.top };
            Rect rcBkgDestL(rcEmem.left, rcEmem.top, pSplit_.lBegin, szElem.cy );
            Rect rcBkgDestM(rcEmem.left + pSplit_.lBegin, rcEmem.top, szElem.cx - ( nStatusW - (pSplit_.lEnd - pSplit_.lBegin) ), szElem.cy );
            Rect rcBkgDestR(rcEmem.right - ((nStatusW) - pSplit_.lEnd), rcEmem.top, (nStatusW) - pSplit_.lEnd, szElem.cy );

            graph.DrawImage(pBitMap_, rcBkgDestL, nStatusW*eStatus, 0, pSplit_.lBegin, nH, UnitPixel, NULL, NULL, NULL);
            graph.DrawImage(pBitMap_, rcBkgDestM, nStatusW*eStatus + pSplit_.lBegin,0,  pSplit_.lEnd - pSplit_.lBegin, nH, UnitPixel, NULL, NULL, NULL);
            graph.DrawImage(pBitMap_, rcBkgDestR, nStatusW*eStatus + pSplit_.lEnd, 0, nStatusW - pSplit_.lEnd, nH, UnitPixel, NULL, NULL, NULL);
        }

        if ( pIcon_ )
        {
            SIZE szIcon = { 0 };
            szIcon.cx = pIcon_->GetWidth();
            szIcon.cy = pIcon_->GetHeight();

            Rect rcDest(rcEmem.left + (nTextOff_ - szIcon.cx)/2, rcEmem.top + ( rcEmem.bottom - rcEmem.top - szIcon.cy )/2, szIcon.cx , szIcon.cy );
            graph.DrawImage(pIcon_, rcDest, 0, 0, szIcon.cx, szIcon.cy, UnitPixel, NULL, NULL, NULL);
        }

        if ( bGDIPlushEnable_ && !wstrText_.empty() )
        {
            UINT uFormat = DT_SINGLELINE | DT_VCENTER |DT_NOPREFIX | DT_EDITCONTROL;
            if ( nTextOff_ > 0 )
            {
                uFormat |= DT_LEFT;
            }
            else
            {
                uFormat |= DT_CENTER;
            }

            FontFamily fontFamily(lf_.lfFaceName);
            StringFormat strformat;
            if ( ( uFormat& DT_CENTER ) == DT_CENTER )
            {
                strformat.SetAlignment( StringAlignmentCenter  );
            }
            else if ( ( uFormat& DT_RIGHT ) == DT_RIGHT )
            {
                strformat.SetAlignment( StringAlignmentFar  );
            }
            else if ( (uFormat &  DT_LEFT) == DT_LEFT )
            {
                strformat.SetAlignment( StringAlignmentNear  );
            }
            int nHeight = -lf_.lfHeight;

            FontStyle fontStyle = FontStyleRegular;
            if ( lf_.lfWeight > 400 )
            {
                fontStyle =	 FontStyleBold;
            }

            RECT rcEdit = {0};
            memcpy(&rcEdit, &rcEmem, sizeof(RECT));
            InflateRect(&rcEdit, -3, -3 );
            rcEdit.left += nTextOff_;

            Font font(&fontFamily, (REAL)nHeight, fontStyle, UnitPixel);
            Color cl(GetRValue(color_),GetGValue(color_),GetBValue(color_));
            SolidBrush sBrush(cl);

            Graphics graph(hDC);
            RectF RcDest((REAL)rcEdit.left, (REAL)rcEdit.top, (REAL)(rcEdit.right - rcEdit.left), (REAL)(rcEdit.bottom - rcEdit.top) );
            graph.DrawString(wstrText_.c_str(), wstrText_.length(), &font, RcDest, &strformat, &sBrush);
        }
        else if (!wstrText_.empty())
        {
            UINT uFormat = DT_SINGLELINE | DT_VCENTER |DT_NOPREFIX | DT_EDITCONTROL;
            if ( nTextOff_ > 0 )
            {
                uFormat |= DT_LEFT;
            }
            else
            {
                uFormat |= DT_CENTER;
            }
            RECT rcEdit = {0};
            memcpy(&rcEdit, &rcEmem, sizeof(RECT));
            InflateRect(&rcEdit, -3, -3 );
            rcEdit.left += nTextOff_;
            HFONT hfont = ::CreateFontIndirect(&lf_);
            HFONT holdFont = (HFONT)::SelectObject(hDC, hfont);
            COLORREF oldColor = ::SetTextColor(hDC, color_ );
            int oldbkgMode = ::SetBkMode(hDC, TRANSPARENT);
            ::DrawText(hDC, wstrText_.c_str(), -1, &rcEdit, uFormat);
            ::SetBkMode(hDC, oldbkgMode);
            ::SelectObject(hDC, holdFont);
            ::SetTextColor(hDC, oldColor);
            ::DeleteObject(hfont);
        }
    }

    void CDrawButton::SetText( wstring wszText, const LOGFONT lf, const COLORREF color /*= 0x000000 */ )
    {
        wstrText_ = wszText;
        memcpy(&lf_, &lf, sizeof(LOGFONT));
        color_ = color;
        CDrawView::ForceInvalidate();
    }

    void CDrawButton::SetText( wstring wszText )
    {
        wstrText_ = wszText;
        CDrawView::ForceInvalidate();
    }
    void CDrawButton::SetSel( const int nSel, const int nStatus /*= 4*/ )
    {
        nSelIndex_ = nSel;
        nStatusOfSel_ = nStatus;
        CDrawView::ForceInvalidate();
    }

    void CDrawButton::SetIcon( Bitmap* pIcon, const int nTextOff )
    {
        pIcon_ = pIcon;
        nTextOff_ = nTextOff;
    }

    void CDrawButton::SetGDIPlusEnable( const bool bEnable )
    {
        bGDIPlushEnable_ = bEnable;
    }
}